package netWork;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王圆豪
 * Date: 2025-05-17
 * Time: 21:51
 */
public class TcpEchoServer1 {
    //首先要有ServerSocket对象，用来接受端口号对客户端进行监听
    private ServerSocket serverSocket = null;

    public TcpEchoServer1(int port) throws IOException {
        //端口号参数让客户端能找到服务器
        serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务端已开启！");
        //因为随时都可能会有客户端对服务器进行访问，所以要写一个死循环来接收客户端连接
        while (true) {
            //并且使用accept方法阻塞等待客户端连接，连接后会创建Socket对象用于与客户端进行通信
            Socket socket = serverSocket.accept();
            Thread t = new Thread(()->{
                try {
                    processConnection(socket);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
            t.start();
        }

    }

    private void processConnection(Socket socket) throws IOException {
        //打印日志，记录服务端访问情况
        System.out.printf("[%s:%d]客户端已上线！\n", socket.getInetAddress()
                ,socket.getPort());
        //创建输入流和输出流对象用于读写操作
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()) {
            //因为一个连接可能会有多个请求，所以需要一个死循环来不断捕捉请求信息
            while (true){
//                if (socket.isClosed()){
//                    System.out.printf("[%s:%d]客户端已下线！\n", socket.getInetAddress()
//                            ,socket.getPort());
//                    break;
//                }
                byte[] data = new byte[4096];
                int n = inputStream.read(data);
                if (n == -1){
                    System.out.printf("[%s:%d]客户端已下线！\n", socket.getInetAddress()
                            ,socket.getPort());
                    break;
                }
                //将请求中的数据转换为字符串
                String request = new String(data,0,n);
                //处理请求
                String reponse = process(request);
                //返回响应
                outputStream.write(reponse.getBytes());

                //打印日志
                System.out.printf("[%s:%d] req: %s, rep: %s\n",
                        socket.getInetAddress(),socket.getPort(),request,reponse);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            socket.close();
        }
    }

    private String process(String request) {
        //因为是回显服务器，所以直接返回请求中的数据就好
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer1 server1 = new TcpEchoServer1(9090);
        server1.start();
    }
}
